<?php
/************************
 *  Codenova.pl Project
 *  Created by: Kamil Mrzygłód
 *
 *  (c) 2013 by Codenova.pl
 *  All Right Reserved
 ***********************/

namespace Gotcha\App;

// Bootstrap prepares application for start
// by checking files existence and basic
// configuration.

use Gotcha\App\Extensions\GotchaErrorsExtension;
use Gotcha\App\Extensions\GotchaFileSystemExtension;
use Gotcha\App\Extensions\GotchaLogsExtension;
use Gotcha\App\Extensions\GotchaCulturesExtension;
use Gotcha\App\Types\String;

class GotchaBootstrap {
    // Error controller preventing further script
    // from being executed
    static protected $fatal_error = false;

    protected static $error_handler_is_set = false;

    public function __construct() {
        spl_autoload_register(function($class) {
            // Define error
            $class_file_doesnt_exist = false;
            $module_class_file_doesnt_exist = false;

            // We have to define all paths we are searching required files in
            $include_paths = array('/App/Extensions/', '/App/Repositories/', '/App/Database/classes/gotcha/', '/App/Database/classes/gotcha/om/', '/App/Database/classes/gotcha/map/', '/App/Libs/Propel/runtime/lib/util/', '/App/Libs/Propel/runtime/lib/om/', '/App/Libs/Propel/runtime/lib/map/', '/App/Libs/Propel/runtime/lib/query/', '/App/Libs/Propel/runtime/lib/formatter/', '/App/Libs/Propel/runtime/lib/connection/', '/App/Libs/Propel/runtime/lib/exception/', '/App/Libs/Propel/runtime/lib/adapter/', '/App/Libs/Propel/runtime/lib/parser/', '/App/Libs/Propel/runtime/lib/parser/yaml/', '/App/Libs/Propel/runtime/lib/collection/', '/App/Libs/Propel/runtime/lib/config/', '/App/Types/', '/Modules/JasminumNews/Controllers/', '/Modules/JasminumReservations/Controllers/', '/Modules/JasminumGallery/Controllers/',  '/App/Libs/PHPMailer/');

            // Extract file name
            $class_name = explode('\\', $class);

            // Check file existence
            foreach ($include_paths as $include_path) {
                // Since module controllers are often called the same(DefaultController),
                // script will always break a loop on first match
                $dirs = explode('/', $include_path);

                if ($dirs[1] === 'Modules') {
                    $replace_backslash = str_replace('\\', '/', $class);
                    if (!file_exists(GOTCHA_ROOT_DIR.'/'.$replace_backslash.'.php')) {
                        // Define error which prevents system from including file
                        $module_class_file_doesnt_exist = true;
                    } else {
                        $module_class_file_doesnt_exist = false;
                        break; // Break iteration since we found file
                    }
                } else {
                    if (!file_exists(GOTCHA_ROOT_DIR.$include_path.$class_name[count($class_name)-1].'.php')) {
                        // Define error which prevents system from including file
                        $class_file_doesnt_exist = true;
                    } else {
                        $class_file_doesnt_exist = false;
                        break; // Break iteration since we found file
                    }
                }
            }

            // Require file
            if (!$class_file_doesnt_exist) {
                require_once ($class_name[count($class_name)-1].'.php');
            } elseif (!$module_class_file_doesnt_exist) {
                require_once (GOTCHA_ROOT_DIR.'/'.$replace_backslash.'.php');
            } else {
                GotchaErrorsExtension::throwError(new String('Given class '.$class.' does not exist.'));
                exit;
            }
        });
    }

    private function checkRequiredFiles() {
        // We crawl through whole file using SimpleXML.
        // For each node check file existence.

        // Local variables
        $required_file = new String('required.xml');
        $fatal_error = false;

        if (self::checkForFatalError() === false) {
            if (GotchaFileSystemExtension::CheckFileExistence($required_file, new String('App/Config/'))) {
                $required_files = simplexml_load_file('App/Config/'.$required_file);

                foreach ($required_files->file as $file) {
                    if (!GotchaFileSystemExtension::CheckFileExistence(new String((string)$file['name']), new String((string)$file['path']))) {
                        GotchaErrorsExtension::throwError(new String(GotchaCulturesExtension::getTranslation(new String('REQUIRED_FILE_DOESNT_EXIST'))), new String((string)$file['path'].(string)$file['name']));

                        // New log entry
                        GotchaLogsExtension::createNewLogEntry(new String(GotchaCulturesExtension::getTranslation(new String('REQUIRED_FILE_DOESNT_EXIST'))), new String((string)$file['path'].(string)$file['name']));

                        // Set fatal error to true to prevent application from executing
                        $fatal_error = true;
                    }
                }

                // Set fatal error visible outside method
                ($fatal_error === true) ? self::$fatal_error = true : self::$fatal_error = false;
            } else {
                GotchaErrorsExtension::throwError(new String(GotchaCulturesExtension::getTranslation(new String('FILE_DOESNT_EXIST'))), $required_file);
                self::$fatal_error = true;
            }
        }

        self::checkForFatalError();
    }

    protected static function checkForFatalError() {
        if (self::$fatal_error === true) {
            // Terminate application
            echo GotchaCulturesExtension::getTranslation(new String('APPLICATION_INITIALIZATION_CRITICAL_ERROR'));
            exit;
        }
    }

    protected static function xmlFileHandler(String $file, String $key)
    {
        return GotchaFileSystemExtension::xmlFileHandler(new String('/'.$file), $key);
    }

    public function init() {
        // Set headers
        header ('Content-Type: text/html; charset=UTF-8');

        // We have to enable error handler
        if(!self::$error_handler_is_set) {
            $obj = new GotchaErrorsExtension();
            set_error_handler(array($obj, 'gotchaErrorHandler'));
            self::$error_handler_is_set = true; // Prevent application from calling handler once more
        }

        // Propel initialization
        require_once GOTCHA_ROOT_DIR.'/App/Libs/Propel/runtime/lib/Propel.php'; // Propel main file
        \Propel::init(GOTCHA_ROOT_DIR.'/App/Database/conf/gotcha-conf.php'); // Propel config

        // Collation
        $con = \Propel::getConnection();
        $con->query('SET NAMES UTF8');

        self::checkRequiredFiles();

        // Start a session
        session_start();
    }
}